package com.web.web.request;

import com.web.web.annotation.NoLoginRequired;
import com.web.web.session.AfterLoginRequired;
import com.web.web.session.RedisSession;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class LoginInterceptor extends HandlerInterceptorAdapter {

    private final AfterLoginRequired afterLoginRequired;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        if (response.isCommitted()) {
            response.sendError(401);
            return false;
        }
        if (!(request instanceof RedisSessionHttpServletRequest)) {
            response.sendError(401);
            return false;
        }
        HttpSession session = request.getSession(true);
        //web控制器方法
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        if (handlerMethod.getMethodAnnotation(NoLoginRequired.class) != null || handlerMethod.getBeanType().getAnnotation(NoLoginRequired.class) != null) {
            if (afterLoginRequired == null) {
                return true;
            }
            return afterLoginRequired.handle(request, false);
        }

        if (!(session instanceof RedisSession)) {
            response.sendError(401);
            return false;
        }

        try {
            if (!((RedisSession) session).getSessionUser().isLogin()) {
                response.sendError(401);
                return false;
            } else if (this.afterLoginRequired == null) {
                return true;
            } else {
                boolean handle = this.afterLoginRequired.handle(request, true);
                if (!handle) {
                    response.sendError(401);
                }
                return handle;
            }
        } catch (Exception e) {
            response.sendError(401);
            return false;
        }
    }


}
